package com.chagee.store.operation.server.service.biz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.chagee.lark.anno.ExceptionLarkNotice;
import com.chagee.lark.enums.UrgentTypeEnum;
import com.chagee.payment.sdk.dto.request.CreateTradeOrderReqDto;
import com.chagee.payment.sdk.dto.resp.CreateTradeOrderResp;
import com.chagee.payment.sdk.utils.AjaxResult;
import com.chagee.store.operation.api.enums.PayTypeEnum;
import com.chagee.store.operation.api.enums.SettlementStatusEnum;
import com.chagee.store.operation.api.response.PayResultResponse;
import com.chagee.store.operation.api.response.vo.CreateTradeOrderVO;
import com.chagee.store.operation.common.constant.CommonConstant;
import com.chagee.store.operation.common.constant.ResultConstant;
import com.chagee.store.operation.common.exception.BizErrorCode;
import com.chagee.store.operation.common.exception.BizException;
import com.chagee.store.operation.server.entity.StoreSettlementDO;
import com.chagee.store.operation.server.event.service.StoreSettlementBaseService;
import com.chagee.store.operation.server.model.param.CreateTradeOrderParam;
import com.chagee.store.operation.server.model.response.CreateOrderResponse;
import com.chagee.store.operation.server.model.vo.PaymentResultVO;
import com.chagee.store.operation.server.service.third.PaymentService;
import com.chagee.store.operation.server.utils.DateUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @Author : hk
 * @Date : 2024/10/22
 */

@Slf4j
@Service
public class PaymentBizService {


	@Resource
	private StoreSettlementBaseService storeSettlementBaseService;

	@Resource
	private PaymentService paymentService;

	@Value("${payment.url}")
	private String url;
	@Value("${payment.appId}")
	private String appId;
	@Value("${payment.publicKey}")
	private String publicKey;
	@Value("${payment.privateKey}")
	private String privateKey;
	@Value("${payment.callbackUrl}")
	private String callbackUrl;

	/**
	 * 去支付结算单
	 *
	 * @param createTradeOrderParam
	 * @return 返回值
	 */
	@ExceptionLarkNotice(bizType = "结算单预支付", title = "预支付", urgentType = UrgentTypeEnum.APP_PHONE)
	public PaymentResultVO createOrder(CreateTradeOrderParam createTradeOrderParam) {

		PaymentResultVO paymentResultVO = new PaymentResultVO();
		if (Objects.isNull(createTradeOrderParam.getAmount())) {
			paymentResultVO.setCode(BizErrorCode.NO_ACCOUNT_FAILED.getErrorCode());
			paymentResultVO.setMag(BizErrorCode.NO_ACCOUNT_FAILED.getErrorMsg());
			return paymentResultVO;
		}
		StoreSettlementDO storeSettlementDO = storeSettlementBaseService.querySettlement(createTradeOrderParam.getOutOrderNo());

		if (Objects.isNull(storeSettlementDO)) {
			log.info("根据结算单{}未查询结算单信息 ", createTradeOrderParam.getOutOrderNo());
			paymentResultVO.setCode(BizErrorCode.ORDER_NOT_EXIST.getErrorCode());
			paymentResultVO.setMag(BizErrorCode.ORDER_NOT_EXIST.getErrorMsg());
			return paymentResultVO;
		}
		if (!SettlementStatusEnum.WAIT_PAY.getType().equals(storeSettlementDO.getDocumentStatus())) {
			paymentResultVO.setCode(BizErrorCode.ORDER_STATUS_FAIL.getErrorCode());
			paymentResultVO.setMag(BizErrorCode.ORDER_STATUS_FAIL.getErrorMsg());
			return paymentResultVO;
		}
		CreateTradeOrderReqDto dto = new CreateTradeOrderReqDto();
		BeanUtils.copyProperties(createTradeOrderParam, dto);
		//外部订单号-通知书编码
//		dto.setOutOrderNo("");
		//付款金额 单位分，无小数
		BigDecimal amount = createTradeOrderParam.getAmount().multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP);

		Date settlementCycle = storeSettlementDO.getSettlementCycle();
		String cycle = DateUtil.format(settlementCycle, DateUtil.YEARS_DATE_PATTERN);
		//商品详情
		dto.setItemInfo(getJSONArray(amount, cycle));
		//付款方门店id-门店编码
//		dto.setPayerStoreId("");
		//收款方门店供应商编码
		dto.setReceiverStoreId(createTradeOrderParam.getSupplierNo());

		//金额（单位：分）
		dto.setAmount(amount);
		//过期时间-自定义
		dto.setExpirationTime(getExpirationTime());
		//支付结果通知地址
		dto.setCallbackUrl(callbackUrl);
		//页面返回地址
//		dto.setPageReturnUrl(pageReturnUrl.concat(dto.getOutOrderNo()));
		dto.setAppId(appId);
		try {
			//调用支付预订单下单接口
			AjaxResult ajaxResult = paymentService.paymentCreateOrder(dto, publicKey, privateKey, url, appId);
			if (Objects.isNull(ajaxResult)) {
				paymentResultVO.setCode(BizErrorCode.NOTICE_FAILED.getErrorCode());
				paymentResultVO.setMag(BizErrorCode.NOTICE_FAILED.getErrorMsg());
				return paymentResultVO;
			}
			String code = String.valueOf(ajaxResult.get(AjaxResult.CODE_TAG));
			paymentResultVO.setCode(code).setMag(String.valueOf(ajaxResult.get(AjaxResult.MSG_TAG)));

			// 操作成功
			if (StringUtils.equals(CommonConstant.ZERO, code)) {
				String jsonData = (String) ajaxResult.get(AjaxResult.DATA_TAG);
				if (StringUtils.isBlank(jsonData)) {
					log.info("结算单{}调用支付预下单接口异常,没有返回值data信息。", dto.getOutOrderNo());
					return paymentResultVO;
				}
				ObjectMapper objectMapper = new ObjectMapper();
				CreateTradeOrderResp data = objectMapper.readValue(jsonData, CreateTradeOrderResp.class);
				if (Objects.isNull(data) || StringUtils.isBlank(data.getOrderNo())) {
					log.info("结算单{}调用支付预下单接口异常,data信息转换为空或者未生成订单号。", dto.getOutOrderNo());
					paymentResultVO.setCode(BizErrorCode.NO_TRADING_CODE_FAILED.getErrorCode());
					paymentResultVO.setMag(BizErrorCode.NO_TRADING_CODE_FAILED.getErrorMsg());
					return paymentResultVO;
				}
				//支付订单编号信息
				storeSettlementDO.setPaymentNo(data.getOrderNo());
				storeSettlementDO.setPayType(PayTypeEnum.ONLINE.getType());
				storeSettlementBaseService.updateById(storeSettlementDO);
				CreateOrderResponse orderResponse = new CreateOrderResponse();
				BeanUtils.copyProperties(data, orderResponse);
				paymentResultVO.setData(orderResponse);
			}
		} catch (Exception e) {
			log.error("{}调用支付预下单接口异常：", dto.getOutOrderNo(), e);
			throw new BizException(BizErrorCode.NOTICE_FAILED);
		}
		return paymentResultVO;
	}

	/**
	 * 编辑商品详情信息
	 *
	 * @return 转成string
	 */
	private String getJSONArray(BigDecimal amount, String cycle) {
		//商品详情，jsonArray字符串
		JSONArray jsonArray = new JSONArray();
		JSONObject jsonObject = new JSONObject();
		jsonObject.put(ResultConstant.PAYMENT_ITEM_NAME, ResultConstant.PAYMENT_ITEM_NAME_DESC.concat(StringUtils.EMPTY).concat(cycle));
		jsonObject.put(ResultConstant.PAYMENT_ITEM_NUM, 1);
		jsonObject.put(ResultConstant.PAYMENT_ITEM_AMOUNT, amount);
		jsonArray.add(jsonObject);
		return jsonArray.toJSONString();
	}

	/**
	 * 获取过期时间
	 *
	 * @return 过期时间
	 */
	@NotNull
	private Date getExpirationTime() {
		Date date = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR, 1);
		date = calendar.getTime();
		return date;
	}

	public String createOrder(StoreSettlementDO storeSettlementDO, String createPerson) {

		String paymentNo = StringUtils.EMPTY;
		//付款金额 单位分，无小数
		BigDecimal amount = storeSettlementDO.getPayMoney().multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP);

		Date settlementCycle = storeSettlementDO.getSettlementCycle();
		String cycle = DateUtil.format(settlementCycle, DateUtil.YEARS_DATE_PATTERN);

		CreateTradeOrderReqDto createTradeOrderReq = new CreateTradeOrderReqDto();
		createTradeOrderReq.setOutOrderNo(storeSettlementDO.getSettlementNo());
		//付款方门店id-门店编码
		createTradeOrderReq.setPayerStoreId(storeSettlementDO.getStoreNo());
		createTradeOrderReq.setPageReturnUrl(CommonConstant.PAGE_RETURN_URL);
		createTradeOrderReq.setCreatePerson(createPerson);

		createTradeOrderReq.setItemInfo(getJSONArray(amount, cycle));
		//收款方门店供应商编码
		createTradeOrderReq.setReceiverStoreId(storeSettlementDO.getSupplierNo());
		//金额（单位：分）
		createTradeOrderReq.setAmount(amount);
		//过期时间-自定义
		createTradeOrderReq.setExpirationTime(getExpirationTime());
		//支付结果通知地址
		createTradeOrderReq.setCallbackUrl(callbackUrl);
		//页面返回地址
//		dto.setPageReturnUrl(pageReturnUrl.concat(dto.getOutOrderNo()));
		createTradeOrderReq.setAppId(appId);

		AjaxResult ajaxResult = paymentService.paymentCreateOrder(createTradeOrderReq, publicKey, privateKey, url, appId);

		if (Objects.isNull(ajaxResult)) {
			throw new BizException(BizErrorCode.ADVANCE_PAYMENT_CREATE_FAILED);
		}

		//String a = JSON.toJSONString(ajaxResult);
		PayResultResponse<?> payResultResponse = JSONObject.parseObject(JSON.toJSONString(ajaxResult), PayResultResponse.class);

		if (StringUtils.equals(CommonConstant.ZERO, payResultResponse.getCode())) {
			String payResultData = parsePayResultData(payResultResponse.getData());

			if (StringUtils.isNotBlank(payResultData)) {
				CreateTradeOrderVO createTradeOrderVO = JSONObject.parseObject(payResultData, new TypeReference<CreateTradeOrderVO>() {
				});
				if (Objects.nonNull(createTradeOrderVO) && StringUtils.isNotBlank(createTradeOrderVO.getOrderNo())) {
					paymentNo = createTradeOrderVO.getOrderNo();
				}
			}
		}
		return paymentNo;
	}

	private String parsePayResultData(Object data) {
		if (data instanceof Integer) {
			return String.valueOf(data);
		} else if (data instanceof String) {
			return String.valueOf(data);
		}
		return null;
	}
}
